﻿using Reviewer.Security;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MySql.Data.MySqlClient;
using System.Data;
using System.Collections.Specialized;
using System.Collections.Generic;
using System;

namespace Test.Reviewer.Security
{
    /// <summary>
    ///This is a test class for RoleProviderTest and is intended
    ///to contain all RoleProviderTest Unit Tests
    ///</summary>
    [TestClass()]
    public class RoleProviderTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for RoleExists
        ///</summary>
        [TestMethod()]
        public void RoleExistsTest()
        {
            RoleProvider provider = System.Web.Security.Roles.Provider as RoleProvider;

            //Verify invalid
            string roleName = "InvalidRoleName";
            bool success = provider.RoleExists(roleName);
            Assert.IsFalse(success);

            //Verify valid
            string[] allRoles = provider.GetAllRoles();
            foreach (string rolename in allRoles)
            {
                success = provider.RoleExists(rolename);
                break;
            }
            Assert.IsTrue(success);
        }

        /// <summary>
        ///A test for RemoveUsersFromRoles
        ///</summary>
        [TestMethod()]
        public void RemoveUsersFromRolesTest()
        {
            RoleProvider provider = System.Web.Security.Roles.Provider as RoleProvider;
            MembershipProvider members = System.Web.Security.Membership.Provider as MembershipProvider;
            int recordCount;
            System.Web.Security.MembershipUserCollection users = members.GetAllUsers(0, 10, out recordCount);
            Assert.AreNotEqual(0, recordCount);
            List<string> userlist = new List<string>();
            foreach (System.Web.Security.MembershipUser user in users)
            {
                userlist.Add(user.UserName);
            }
            string[] usernames = userlist.ToArray();
            userlist.Clear();

            string testIdentifier = DateTime.Now.Ticks.ToString();
            //Create two new roles
            string rolename1 = String.Format("TestRole1 {0}", testIdentifier);
            string rolename2 = String.Format("TestRole2 {0}", testIdentifier);

            provider.CreateRole(rolename1);
            provider.CreateRole(rolename2);

            //add users to roles
            provider.AddUsersToRoles(usernames, new string[2] { rolename1, rolename2 });

            //verify added to role
            bool isInRole = provider.IsUserInRole(usernames[0], rolename1);
            Assert.IsTrue(isInRole);
            isInRole = provider.IsUserInRole(usernames[0], rolename2);
            Assert.IsTrue(isInRole);

            isInRole = provider.IsUserInRole(usernames[usernames.Length - 1], rolename1);
            Assert.IsTrue(isInRole);
            isInRole = provider.IsUserInRole(usernames[usernames.Length - 1], rolename2);
            Assert.IsTrue(isInRole);

            //test the count of users in the role.
            Assert.AreEqual(usernames.Length, provider.GetUsersInRole(rolename1).Length);
            Assert.AreEqual(usernames.Length, provider.GetUsersInRole(rolename2).Length);

            provider.RemoveUsersFromRoles(usernames, new string[2] { rolename1, rolename2 });

            isInRole = provider.IsUserInRole(usernames[0], rolename1);
            Assert.IsFalse(isInRole);
            isInRole = provider.IsUserInRole(usernames[0], rolename2);
            Assert.IsFalse(isInRole);

            isInRole = provider.IsUserInRole(usernames[usernames.Length - 1], rolename1);
            Assert.IsFalse(isInRole);
            isInRole = provider.IsUserInRole(usernames[usernames.Length - 1], rolename2);
            Assert.IsFalse(isInRole);

            bool success = provider.DeleteRole(rolename1, true);
            Assert.IsTrue(success);
            success = provider.DeleteRole(rolename2, true);
            Assert.IsTrue(success);
        }

        /// <summary>
        ///A test for GetRolesForUser
        ///</summary>
        [TestMethod()]
        public void GetRolesForUserTest()
        {
            RoleProvider provider = System.Web.Security.Roles.Provider as RoleProvider; // TODO: Initialize to an appropriate value
            MembershipProvider members = System.Web.Security.Membership.Provider as MembershipProvider;

            //create roles
            string roleName = "TestRole " + DateTime.Now.Ticks.ToString();
            provider.CreateRole(roleName);

            int totalRecords;
            bool found = false;
            foreach (System.Web.Security.MembershipUser user in members.GetAllUsers(0, 1, out totalRecords))
            {
                provider.AddUsersToRoles(new string[] { user.UserName }, new string[] { roleName });

                string[] rolesForUser = provider.GetRolesForUser(user.UserName);
                Assert.AreNotEqual(0, rolesForUser.Length);

                foreach (String role in rolesForUser)
                {
                    if (role.Equals(roleName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        found = true;
                        break;
                    }
                }

                provider.RemoveUsersFromRoles(new string[] { user.UserName }, new string[] { roleName });
                break;

            }

            Assert.IsTrue(found);

            bool success = provider.DeleteRole(roleName, true);
            Assert.IsTrue(success);
        }

        /// <summary>
        ///A test for GetAllRoles
        ///</summary>
        [TestMethod()]
        public void GetAllRolesTest()
        {
            RoleProvider provider = System.Web.Security.Roles.Provider as RoleProvider; // TODO: Initialize to an appropriate value
            string[] actual = provider.GetAllRoles();
            Assert.AreNotEqual(0, actual.Length);
        }

        /// <summary>
        ///A test for FindUsersInRole
        ///</summary>
        [TestMethod()]
        public void FindUsersInRoleTest()
        {
            RoleProvider provider = System.Web.Security.Roles.Provider as RoleProvider; // TODO: Initialize to an appropriate value
            MembershipProvider members = System.Web.Security.Membership.Provider as MembershipProvider;

            //create roles
            string roleName = "TestRole " + DateTime.Now.Ticks.ToString();
            provider.CreateRole(roleName);

            int totalRecords;
            foreach (System.Web.Security.MembershipUser user in members.GetAllUsers(0, 1, out totalRecords))
            {
                provider.AddUsersToRoles(new string[] { user.UserName }, new string[] { roleName });

                string[] usersInRole = provider.FindUsersInRole(roleName, user.UserName.Substring(0, 1) + "%");
                Assert.AreEqual(1, usersInRole.Length);

                provider.RemoveUsersFromRoles(new string[] { user.UserName }, new string[] { roleName });
                break;
            }
            Assert.AreNotEqual(0, totalRecords);

            bool success = provider.DeleteRole(roleName, true);
            Assert.IsTrue(success);
        }
    }
}
